package by.pavlyukevich.paymentsystem.panel.user;

import javax.inject.Inject;
import javax.persistence.metamodel.SingularAttribute;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.springframework.orm.jpa.JpaSystemException;

import by.pavlyukevich.paymentsystem.add.AbstractDataProvider;
import by.pavlyukevich.paymentsystem.add.ErrorEvent;
import by.pavlyukevich.paymentsystem.add.PanelUpdateEvent;
import by.pavlyukevich.paymentsystem.dataaccess.filter.AccountFilter;
import by.pavlyukevich.paymentsystem.dataaccess.filter.CardFilter;
import by.pavlyukevich.paymentsystem.dataaccess.filter.Filter;
import by.pavlyukevich.paymentsystem.dataaccess.filter.UserAccountFilter;
import by.pavlyukevich.paymentsystem.datamodel.user.UserAccount;
import by.pavlyukevich.paymentsystem.datamodel.user.UserAccount_;
import by.pavlyukevich.paymentsystem.panel.AccountListPanel;
import by.pavlyukevich.paymentsystem.panel.MyPagingNavigator;
import by.pavlyukevich.paymentsystem.panel.card.CardListPanel;
import by.pavlyukevich.paymentsystem.services.user.UserAccountService;

public class UserAccountListPanel extends Panel {

	@Inject
	private UserAccountService userAccountService;
	private UserAccountFilter userAccountFilter;
	private Panel respPanel;

	public UserAccountListPanel(String id) {
		this(id, new UserAccountFilter());
	}

	public UserAccountListPanel(String id, UserAccountFilter userAccountFilter) {
		super(id);
		this.userAccountFilter = userAccountFilter;
		this.respPanel = this;
	}

	@Override
	protected void onInitialize() {
		setOutputMarkupId(true);

		UserAccountDataProvider userAccountDP = new UserAccountDataProvider(UserAccount_.login,
				userAccountFilter);

		final WebMarkupContainer userAccountTable = new WebMarkupContainer("userAccount-table");
		userAccountTable.setOutputMarkupId(true);
		add(userAccountTable);

		DataView<UserAccount> dataView = new DataView<UserAccount>("userAccount-row",
				userAccountDP, 20) {

			@Override
			protected void populateItem(Item<UserAccount> item) {

				final UserAccount userAccount = item.getModelObject();

				item.add(new Label("login"));
				item.add(new Label("password"));
				item.add(new Label("userType"));

				AjaxLink<Void> ownerLink = new AjaxLink<Void>("owner") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						Panel panel = (userAccount.getIndividual() != null) ? new IndividualEditPanel(
								"ac-panel", userAccount.getIndividual(), respPanel)
								: new ContractorEditPanel("ac-panel", userAccount.getContractor(),
										respPanel);
						send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target, panel));
					}
				};
				ownerLink.setBody(new Model<String>(
						(userAccount.getIndividual() != null) ? userAccount.getIndividual()
								.getFamily() : userAccount.getContractor().getName()));
				item.add(ownerLink);

				item.add(new AjaxLink<Void>("cards") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						send(getPage(), Broadcast.BREADTH,
								new PanelUpdateEvent(target, new CardListPanel("ac-panel",
										new CardFilter().setUserAccount(userAccount))));
					}
				});

				item.add(new AjaxLink<Void>("accounts") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						send(getPage(), Broadcast.BREADTH,
								new PanelUpdateEvent(target, new AccountListPanel("ac-panel",
										new AccountFilter().setUserAccount(userAccount))));
					}
				});

				item.add(new AjaxLink<Void>("delete") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						try {
							userAccountService.delete(userAccount);
							target.add(respPanel);
						} catch (JpaSystemException e) {
							error(new ResourceModel("t.error.unableToDelete").getObject());
							send(getPage(), Broadcast.BREADTH, new ErrorEvent(target));

						}
					}
				});

				item.add(new AjaxLink<Void>("edit") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
								new UserAccountEditPanel("ac-panel", userAccount, respPanel)));
					}
				});
			}

		};

		userAccountTable.add(dataView);
		add(new AjaxLink<Void>("new") {

			@Override
			public void onClick(AjaxRequestTarget target) {
				send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
						new UserAccountEditPanel("ac-panel", new UserAccount(), respPanel)));
			}
		});

		add(new MyPagingNavigator("paging", dataView));

		add(new OrderByBorder<SingularAttribute<UserAccount, ?>>("sortByLogin", UserAccount_.login,
				userAccountDP));

		super.onInitialize();
	};

	private class UserAccountDataProvider extends AbstractDataProvider<UserAccount> {
		public UserAccountDataProvider(SingularAttribute<UserAccount, ?> sortParam,
				Filter<UserAccount> filter) {
			super(sortParam, filter, userAccountService);
		}
	};

}
